/**********************************************************************
 * Filename: CalendarDate.java
 * Created: 2012/05/04
 * @author Fernando Brito e Abreu
 **********************************************************************/
package org.quasar.copaPaises.businessLayer;

import java.lang.reflect.Array;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;

//import javax.swing.text.html.HTMLDocument.Iterator;

public class CalendarDate
{
	public static Set<CalendarDate> allInstances = new HashSet<CalendarDate>();

	private int day;
	private int month;
	private int year;

	/**********************************************************************
	 * Default constructor
	 **********************************************************************/
	public CalendarDate(){
		
		allInstances.add(this);
	}

	/**********************************************************************
	 * Parameterized constructor
	 * @param day the day to initialize
	 * @param month the month to initialize
	 * @param year the year to initialize
	 **********************************************************************/
	public CalendarDate(int day, int month, int year)
	{
		this.day = day;
		this.month = month;
		this.year = year;
		allInstances.add(this);
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the day of the calendarDate
	 **********************************************************************/
	public int day()
	{
		return day;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param day the day to set
	 **********************************************************************/
	public void setDay(int day)
	{
		this.day = day;
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the month of the calendarDate
	 **********************************************************************/
	public int month()
	{
		return month;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param month the month to set
	 **********************************************************************/
	public void setMonth(int month)
	{
		this.month = month;
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the year of the calendarDate
	 **********************************************************************/
	public int year()
	{
		return year;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param year the year to set
	 **********************************************************************/
	public void setYear(int year)
	{
		this.year = year;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param day the day to set
	 * @param month the month to set
	 * @param year the year to set
	 **********************************************************************/
	public void init(int day, int month, int year)
	{
		this.day = day;
		this.month = month;
		this.year = year;
		//	TODO
		//	self.day := day;
		//	 self.month := month;
		//	 self.year := year;
	}

	//	POST-CONDITIONS (TODO)
	/*
	post CallendarDateWasInitialized
		((day.isDefined and month.isDefined) and year.isDefined)

	 */

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param date the date to set
	 **********************************************************************/
	public void initS(String date)	{
		
		this.year = Integer.parseInt(date.substring(0,4));
		this.month = Integer.parseInt(date.substring(6,7));
		this.day = Integer.parseInt(date.substring(9,10));
		
//		System.out.println(day()+"/"+month()+"/"+year());
		
		//	self.year := date.substring(1,4).toInteger;
		//	 self.month := date.substring(6,7).toInteger;
		//	 self.day := date.substring(9,10).toInteger;
	}

	//	POST-CONDITIONS (TODO)
	/*
	post CallendarDateWasInitialized
		((self.day.isDefined and self.month.isDefined) and self.year.isDefined)

	 */

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public boolean isAfter(CalendarDate t)	{

		if((this.year==t.year && this.month==t.month && this.day > t.day ) ||	
				(this.year==t.year && this.month > t.month ) || (this.year > t.year ))
			return true;
		return false;

		//	return if (self.year = t.year) then if (self.month = t.month) then (self.day > t.day) else (self.month > t.month) endif else (self.year > t.year) endif
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public boolean isBefore(CalendarDate t)
	{
		if((this.year==t.year && this.month==t.month && this.day < t.day ) ||	
				(this.year==t.year && this.month < t.month ) || (this.year < t.year ))
			return true;
		return false;

		//	return if (self.year = t.year) then if (self.month = t.month) then (self.day < t.day) else (self.month < t.month) endif else (self.year < t.year) endif
		//return true;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param x the x to set
	 * @param y the y to set
	 **********************************************************************/
	public static boolean isDivisible(int x, int y)
	{

		return x%y == 0;

		//	return (((x div y) * y) = x)
		//return true;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public boolean isEqual(CalendarDate t)
	{
		return (this.year == t.year && this.month == t.month && this.day == t.day);

		//	return (((self.year = t.year) and (self.month = t.month)) and (self.day = t.day))
		//return true;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 **********************************************************************/
	public boolean isLeap()
	{	
		return (this.year%4==0);

		//	return if (self.isDivisible(self.year, 400) or self.isDivisible(self.year, 4)) then true else if self.isDivisible(self.year, 100) then false else if self.isDivisible(self.year, 4) then true else false endif endif endif
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param date the date to set
	 **********************************************************************/
	public static CalendarDate stringToDate(String date) {
		
//		int date_year = Integer.parseInt(date.substring(0,4));
//		int date_month = Integer.parseInt(date.substring(6,7));
//		int date_day = Integer.parseInt(date.substring(9,10));
//		System.out.println("ano: " + date_year + ", mes: " + date_month + ", dia : " + date_day);
//
////		CalendarDate[] array = (CalendarDate[]) allInstances.toArray();
//		
//		System.out.println("array: " + array.length);
//		System.out.println("all: " + allInstances.size());
//		
////		Iterator<CalendarDate> i = allInstances.iterator();
//		int iterator = 0;
//		boolean found = false;
//		
//		while(iterator < allInstances.size() && !found){
////			CalendarDate dt1 = i.next();
//			int day_it = allInstances[iterator].day;
//			int month_it = array[iterator].month;
//			int year_it = array[iterator].year;
////			
//			if(date_day == day_it && date_month == month_it && date_year == year_it){
//				found = true;
//			}
////			i.remove();
//			
//			iterator++;
//		}
//
//		//	TODO
//		//	date_year := date.substring(1,4);
//		//	 date_month := date.substring(6,7);
//		//	 date_day := date.substring(9,10);
//		//	 result := CalendarDate.allInstances->select(cd : CalendarDate | (((cd.year = date_year.toInteger) and (cd.month = date_month.toInteger)) and (cd.day = date_day.toInteger)))->asSequence->first;
//		//	 if result.isUndefined then result := new CalendarDate(((('D' + date_year) + date_month) + date_day));
//		//	 result.initS(date) end;
////		return dt1;
//			
//			if(!found){
//				return new CalendarDate(date_day, date_month, date_year);
//			}
//				
//				
//			
//		return array[iterator-1];
		
		return null;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public int yearsSince(CalendarDate t)
	{
		if((t.month < this.month) || (this.month == t.month && t.day < this.day))
			return (t.year-this.year-1);
		
		return (t.year - this.year);

		//	return if ((self.month < t.month) or ((self.month = t.month) and (self.day < t.day))) then ((self.year - t.year) - 1) else (self.year - t.year) endif
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	/**********************************************************************
	 * Object serializer
	 **********************************************************************/
	public String toString()
	{
		return "CalendarDate [day=" + day + ", month=" + month + ", year=" + year + "]\n";
	}

}
